from datetime import datetime
from calendar import monthrange

from django.db.models import Q, Sum
from django.shortcuts import render
from django.http import JsonResponse

from main.models import Account



class Statistics:

    def get_table_two(self, request):
        """ Получаем все необходимое для отображения второй таблицы """

        good_accounts_count = Account.objects.filter(Q(status='ok') | Q(status='product_is_paid_for')).count()
        bad_accounts_count = Account.objects.filter(status='ban').count()
        amount = Account.objects.aggregate(amount=Sum('purchase_amount'))['amount']
        context = {
            'good_accounts_count': good_accounts_count,
            'bad_accounts_count': bad_accounts_count,
            'amount': amount,
        }
        
        return render(request, 'main/table_two.html', context)


    def get_amount_of_specified_time_interval(self, request):
        """ Получаем сумму указанного промежукта времени """

        def convert_date_to_object(date):
            """ Преобразовываем дату в объект """

            return datetime.strptime(date, '%Y-%m-%d')


        def get_necessary_accounts(start_day, end_day):
            """ Получаем нужные аккаунты """

            necessary_accounts = []
            accounts = Account.objects.filter(Q(status='ok') | Q(status='product_is_paid_for') | Q(status='ban'))

            for account in accounts:
                account_date = account.payment_date
                account_date = f'{account_date.year}-{account_date.month}-{account_date.day}'
                account_date = convert_date_to_object(account_date)
                if start_day <= account_date and account_date <= end_day:
                    necessary_accounts.append(account)

            return necessary_accounts


        def get_total_amount(necessary_accounts):
            """ Получаем общую сумму """

            return sum([item.purchase_amount for item in necessary_accounts])


        # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

        start_day = convert_date_to_object(request.GET.get('start_day'))
        end_day = convert_date_to_object(request.GET.get('end_day'))
        necessary_accounts = get_necessary_accounts(start_day, end_day)
        total_amount = get_total_amount(necessary_accounts)
        return JsonResponse({'total_amount': total_amount})


    def get_list_of_days_of_month(self, month, year):
        """ Получаем количество дней месяца """

        return list(range(1, monthrange(2022, 8)[1] + 1))


    def get_amount_for_each_day(self, month, year, list_of_days_of_month):
        """ Получаем сумму на каждый день """

        result = {}

        for day in list_of_days_of_month:
            amount = sum([account.purchase_amount
                         for account in Account.objects.filter(payment_date__day=day,
                                                               payment_date__month=month,
                                                               payment_date__year=year)])
            result[day] = amount

        return result


    def get_data_for_statistics_of_specified_day(self, request):
        """ Получаем данные для статистики указанного дня """

        day = request.GET.get('d')
        month = request.GET.get('m')
        year = request.GET.get('y')

        list_of_days_of_month = self.get_list_of_days_of_month(month, year)
        amount_for_each_day = self.get_amount_for_each_day(month, year, list_of_days_of_month)
        return amount_for_each_day


    def get_data_for_statistics(self, request):
        """ Получаем данные для статистики """

        data = self.get_data_for_statistics_of_specified_day(request)
        return JsonResponse(data)


    def get_necessary_information(self, request):
        """ Получаем нужную информацию """

        if request.GET.get('start_day'):
            return self.get_amount_of_specified_time_interval(request)
        if request.GET.get('statistics_data'):
            return self.get_data_for_statistics(request)
        else:
            return self.get_table_two(request)


def change_status_to_ban(model_admin, request, queryset):
    """ Меняем статус аккаунтов на 'Бан' """

    for account in queryset:
        account.status = 'ban'
        account.save()


def change_status_to_ok(model_admin, request, queryset):
    """ Меняем статус аккаунтов на 'OK' """

    for account in queryset:
        account.status = 'ok'
        account.save()
